package com.hlk.file.controller;

import com.hlk.file.FileUploadControllerApi;
import com.hlk.enums.ResponseStatusEnum;
import com.hlk.exception.HuaException;
import com.hlk.file.config.ResourceConfig;
import com.hlk.file.service.FileUploadService;
import com.hlk.pojo.bo.NewAdminBO;
import com.hlk.result.Result;
import com.hlk.utils.FileUtils;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.model.Filters;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hlk
 * @version 1.0
 * @date 2020-12-22 10:02
 */
@RestController
public class FileUploadController implements FileUploadControllerApi {
    @Autowired
    private ResourceConfig resourceConfig;
    @Autowired
    private FileUploadService fileUploadService;
    @Autowired
    private GridFSBucket gridFSBucket;

    @Override
    public Result uploadFace(String userId, MultipartFile file) throws Exception {
        if (file == null) {
            throw new HuaException(ResponseStatusEnum.FILE_UPLOAD_NULL_ERROR);
        }
        if (StringUtils.isBlank(userId)) {
            throw new HuaException(ResponseStatusEnum.UN_LOGIN);
        }

        String filename = file.getOriginalFilename();
        String path = "";
        if (StringUtils.isNotBlank(filename)) {
            String[] fileNamrArr = filename.split("\\.");

            // 获取文件后缀
            String suffix = fileNamrArr[fileNamrArr.length - 1];
            // 判断后缀是否符合规范
            if (!suffix.equalsIgnoreCase("png") && !suffix.equalsIgnoreCase("jpg") && !suffix.equalsIgnoreCase("jpeg")) {
                return Result.errorCustom(ResponseStatusEnum.FILE_FORMATTER_FAILD);
            }

            //上传文件
            path = fileUploadService.uploadFdfs(file, suffix);
            path = resourceConfig.getHost() + path;
        } else {
            throw new HuaException(ResponseStatusEnum.FILE_UPLOAD_FAILD);
        }

        return Result.ok(path);
    }

    @Override
    public Result uploadToGridFS(NewAdminBO newAdminBO) throws Exception {
        String file64 = newAdminBO.getImg64();
        byte[] bytes = new BASE64Decoder().decodeBuffer(file64.trim());
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        ObjectId objectId = gridFSBucket.uploadFromStream(newAdminBO.getUsername() + ".png", inputStream);
        String fileIdStr = objectId.toString();
        return Result.ok(fileIdStr);
    }

    @Override
    public void readInGridFS(String faceId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 0. 判断参数
        if (StringUtils.isBlank(faceId) || faceId.equalsIgnoreCase("null")) {
            throw new HuaException(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }

        // 1. 从gridfs中读取
        File adminFace = readGridFSByFaceId(faceId);

        // 2. 把人脸图片输出到浏览器
        FileUtils.downloadFileByStream(response, adminFace);
    }

    /**
     * 通过faceId获取到图片
     *
     * @param faceId
     * @return
     * @throws Exception
     */
    private File readGridFSByFaceId(String faceId) throws Exception {

        GridFSFindIterable gridFSFiles
                = gridFSBucket.find(Filters.eq("_id", new ObjectId(faceId)));

        GridFSFile gridFS = gridFSFiles.first();

        if (gridFS == null) {
            throw new HuaException(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }

        String fileName = gridFS.getFilename();
        System.out.println(fileName);

        // 获取文件流，保存文件到本地或者服务器的临时目录
        File fileTemp = new File("/workspace/temp_face");
        if (!fileTemp.exists()) {
            fileTemp.mkdirs();
        }

        File myFile = new File("/workspace/temp_face/" + fileName);

        // 创建文件输出流
        OutputStream os = new FileOutputStream(myFile);
        // 下载到服务器或者本地
        gridFSBucket.downloadToStream(new ObjectId(faceId), os);

        return myFile;
    }

    @Override
    public Result readFace64InGridFS(String faceId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 0. 获得gridfs中人脸文件
        File myface = readGridFSByFaceId(faceId);

        // 1. 转换人脸为base64
        String base64Face = FileUtils.fileToBase64(myface);

        return Result.ok(base64Face);
    }

    @Override
    public Result uploadSomeFiles(String userId, MultipartFile[] files) throws Exception {
        // 声明list，用于存放多个图片的地址路径，返回到前端
        List<String> imageUrlList = new ArrayList<>();
        if (files != null && files.length > 0) {
            for (MultipartFile file : files) {
                String path = "";
                if (file != null) {
                    // 获得文件上传的名称
                    String fileName = file.getOriginalFilename();

                    // 判断文件名不能为空
                    if (StringUtils.isNotBlank(fileName)) {
                        String fileNameArr[] = fileName.split("\\.");
                        // 获得后缀
                        String suffix = fileNameArr[fileNameArr.length - 1];
                        // 判断后缀符合我们的预定义规范
                        if (!suffix.equalsIgnoreCase("png") &&
                                !suffix.equalsIgnoreCase("jpg") &&
                                !suffix.equalsIgnoreCase("jpeg")
                        ) {
                            continue;
                        }

                        // 执行上传
                        path = fileUploadService.uploadFdfs(file, suffix);
//                        path = uploaderService.uploadOSS(file, userId, suffix);

                    } else {
                        continue;
                    }
                } else {
                    continue;
                }

                String finalPath = "";
                if (StringUtils.isNotBlank(path)) {
                    finalPath = resourceConfig.getHost() + path;
//                    finalPath = fileResource.getOssHost() + path;
                    // FIXME: 放入到imagelist之前，需要对图片做一次审核
                    imageUrlList.add(finalPath);
                } else {
                    continue;
                }
            }
        }

        return Result.ok(imageUrlList);
    }
}
